home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 209_01 / simplib1.c < prev    next >
Text File  |  1990-03-03  |  8KB  |  275 lines

  1. /* SIMPLIB1.C   VERS:- 01.00  DATE:- 09/26/86  TIME:- 09:39:26 PM */
  2. /* 
  3. Description:
  4.  
  5. routines for input of data and control values for simplex minimization:
  6.     definition of the aggregate <data>, with a 
  7.         dummy structure declaration
  8.     usage message displayed on command line error         = use_mess()
  9.     opening of files for input and optional output        = file()
  10.     input of variables and data                = read_data()
  11.  
  12. the routines are (largely) independent of the function and data to be fit
  13.     (coded in XXXXFITn), and they (generally) need not be altered when 
  14.     XXXXFITn is modified.
  15.  
  16. the DEFINITION of the aggregate <data> and the functions <use_mess()>, 
  17. <file()>, and <read_data()> are in a separate file, SIMPLIB1; 
  18. this is to to allow expansion of the aggregate <data> by overwriting 
  19. most of SIMPLIB1;
  20. the SIMPLIB1 routines are entered only once, at the start of execution.
  21.  
  22. the DECLARATION of <struct dat> according to the requirements of the model
  23. function described by <func()> is given in XXXXFITn;
  24. <func()>, etc. reference the aggregate <data> as external to XXXXFITn, 
  25. but through the structure <dat>, declared locally in XXXXFITn and with
  26. mnemonic member names suitable for use in coding of <func()>, etc.;
  27. for more detail on this arrangement, see the header and documentation 
  28. of XXXXFITn and SIMPMAIN.
  29.  
  30.  
  31. By J.A. Rupley, Tucson, Arizona
  32. Coded for ECO C compiler, version 3.40
  33. */
  34.  
  35. /* page eject */
  36.  
  37. #include <stdio.h>
  38. #include <ctrlcnst.h>
  39.  
  40.  
  41. #define NDATA        300    /* space for NDATA double values are allocated
  42.                 as storage at the start of the SIMPLIB1
  43.                 module; this allocation can be changed, 
  44.                 according to the need for more data points, as
  45.                 balanced against the need for possible 
  46.                 expansion of the code of <main()> & <func()> */
  47.  
  48.  
  49. #define NPARM        10    /* do NOT change this define */
  50.  
  51.  
  52.  
  53.                 /* EXTERNALS AND STRUCTURES */
  54.  
  55.                 /* do NOT change any structure */
  56.  
  57.                 /* the use of a dummy structure in the
  58.                 definition of <data> is to allow: 
  59.                 (1) a generalized read of the data file into
  60.                 the data array, in <read_me>;
  61.                 (2) the "true" declaration of the structure
  62.                 for <data> in a different file, XXXXFITn,
  63.                 that must be recompiled with each change in
  64.                 the function and data being fit;
  65.                 it should not be necessary to recompile
  66.                 this file, SIMPLIB1 */
  67. struct dummy {            
  68.     double dummy ;        
  69. } data[NDATA] ;
  70.  
  71. struct pstruct {
  72.     double val ;
  73.     double parm[NPARM] ;
  74. } ;
  75.  
  76. /* page eject */
  77.  
  78. void use_mess()
  79. {
  80.     void puts() ;
  81.  
  82. puts("\nUsage:") ;
  83. puts("A>simpfitx   [d:]input_file   [[d:]output_file]") ;
  84. puts("   the optional output file can be LST: or a disk file;") ;
  85. puts("   the required input file has the following structure:") ;
  86. puts("     one-line title, with no tabs or ctrl characters;") ;
  87. puts("     lines following give control variables, the starting simplex,") ;
  88. puts("              and the data array;") ;
  89. puts("     the order of entry is fixed by the order in <read_data()>;") ;
  90. puts("              see sample file for structure;") ;
  91. puts("     the one-word descriptors must be present in the data file;") ;
  92. puts("     the data format is free-form (no set field widths);");
  93. puts("\n") ;
  94. puts("      comments at the end of the file are not read by the program") ;
  95. puts("              and any other information to be stored should be there") ;
  96. puts("\n") ;
  97. }                /* END OF USE_MESS            */
  98.  
  99.  
  100.  
  101.  
  102.  
  103. FILE *file(argc, argv, nargv, string)
  104. int argc ; 
  105. char *argv[] ;
  106. int nargv ;
  107. char *string ;
  108. {
  109.     void exit(), printf() ;
  110.     FILE *fptr, *fopen() ;
  111.  
  112.     if (argc < (nargv + 1)) {
  113.         use_mess() ;
  114.         exit (ERROR) ;
  115.     }
  116.  
  117.     if ((fptr = fopen(argv[nargv], string)) == NULL) {
  118.         printf("\nSorry, I cannot open the file.\n\n") ;
  119.         return (fptr) ;
  120.     }
  121.     printf("\nOpen file %s    for \"%s\"\n", argv[nargv], string) ;
  122.  
  123.     return (fptr) ;
  124. }                /* END OF FILE                */
  125.  
  126. /* page eject */
  127.  
  128. /* READ_DATA
  129.     ENTRY OF TITLE, CONTROL VARIABLES, STARTING SIMPLEX, AND DATA
  130.         FROM DISK FILE GIVEN AS ARGUMENT 1 OF COMMAND LINE
  131.     MANIPULATION OF DATA PRIOR TO FITTING SHOULD BE DONE HERE (OR IN
  132.         MAIN())
  133.     THE DISK DATA FILE IS FREE-FORM (IE, WITHOUT FIELD WIDTHS), 
  134.         BUT THE SEQUENCE OF ENTRIES MUST BE EXACTLY AS BELOW
  135.     THE MNEMONIC IDENTIFIERS MUST BE IN THE DATA FILE (THEY ARE
  136.         DISCARDED IN THE READ, BUT ARE ASSUMED TO BE PRESENT)
  137.     THE IDENTIFIERS CANNOT CONTAIN WHITE SPACE
  138.     THE ONE-LINE TITLE CANNOT CONTAIN CONTROL CHARACTERS
  139. */
  140.  
  141. int read_data(argc, argv, fp_out, p_fp_optional)
  142. int argc ;
  143. char *argv[] ;
  144. FILE *fp_out ;
  145. FILE **p_fp_optional ;
  146. {
  147.     register int i, j ;
  148.     char dummy[80] ;
  149.     double *p_x ;
  150.  
  151.     extern char        title[] ;
  152.     extern double         exit_test, quad_test ;
  153.     extern int         iter, maxiter, nparm, nvert, ndata, nfree ;
  154.     extern int        maxquad_skip, prt_cycle, ndatval ;
  155.     extern struct dummy     data[] ;
  156.     extern struct pstruct     p[] ;
  157.  
  158.     char *str_in() ;
  159.     void fpprint(), fsprint(), use_mess() ;
  160.     int func() ;
  161.  
  162.     double atof() ;
  163.     int atoi() ;
  164.     int getc(), iscntrl() ;
  165.     void fprintf(), exit(), fclose() ;
  166.  
  167.     FILE *fptr, *file() ;
  168.  
  169.  
  170.  
  171.  
  172.                     /* open data file specified in the 
  173.                     command line */
  174.     if ((fptr = file(argc, argv, 1, "r")) == NULL)
  175.         exit (ERROR) ;
  176.  
  177.  
  178.  
  179.                     /* open optional output file */
  180.     *p_fp_optional = NULL ;
  181.     if (argc > 2)
  182.         if (!(strcmp(argv[2], "STDLST")))
  183.             *p_fp_optional = stdlst ;
  184.         else if (!(strcmp(argv[2], "LST:")))
  185.             *p_fp_optional = stdlst ;
  186.         else if (!(strcmp(argv[2], "PRINTER")))
  187.             *p_fp_optional = stdlst ;
  188.         else if ((*p_fp_optional = file(argc, argv, 2, "w")) == NULL)
  189.             exit (ERROR) ;
  190.  
  191.  
  192.                     /* read and print
  193.                     title */
  194.     for (i = 0; i < 79; i++) {
  195.         if (iscntrl(title[i] = getc(fptr)))
  196.             break ;
  197.     }
  198.     title[i] = '\0' ;
  199.     fprintf(fp_out, "\n%-s\n", title) ;
  200.  
  201.  
  202.  
  203.                     /* read and print
  204.                     nvert, nparm, ndata, ndatval */
  205.     str_in(fptr, dummy) ;
  206.     fprintf(fp_out, "\nnvert = %d\n",  
  207.             nvert = atoi(str_in(fptr, dummy))) ;
  208.     str_in(fptr, dummy) ;
  209.     fprintf(fp_out, "\nnparm = %d\n",  
  210.             nparm = atoi(str_in(fptr, dummy))) ;
  211.     str_in(fptr, dummy) ;
  212.     fprintf(fp_out, "\nndata = %d\n",  
  213.             ndata = atoi(str_in(fptr, dummy))) ;
  214.     str_in(fptr, dummy) ;
  215.     fprintf(fp_out, "\nndatval = %d\n",  
  216.             ndatval = atoi(str_in(fptr, dummy))) ;
  217.     nfree = nvert - 1 ;
  218.  
  219.  
  220.                     /* read and print
  221.                     iter, maxiter, exit_test, 
  222.                     prt_cycle, quad_test */
  223.     str_in(fptr, dummy) ;
  224.     fprintf(fp_out, "\niter = %d\n",  
  225.             iter = atoi(str_in(fptr, dummy))) ;
  226.     str_in(fptr, dummy) ;
  227.     fprintf(fp_out, "\nmaxquad_skip = %d\n",  
  228.             maxquad_skip = atoi(str_in(fptr, dummy))) ;
  229.     str_in(fptr, dummy) ;
  230.     fprintf(fp_out, "\nexit_test = %20.14e\n",  
  231.             exit_test = atof(str_in(fptr, dummy))) ;
  232.     str_in(fptr, dummy) ;
  233.     fprintf(fp_out, "\nprt_cycle = %d\n",  
  234.             prt_cycle = atoi(str_in(fptr, dummy))) ;
  235.     str_in(fptr, dummy) ;
  236.     fprintf(fp_out, "\nquad_test = %20.14e\n",  
  237.             quad_test = atof(str_in(fptr, dummy))) ;
  238.  
  239.  
  240.  
  241.                     /* read 
  242.                     simplex */
  243.     fprintf(fp_out, "\n\n\n%-79s\n", str_in(fptr, dummy)) ;
  244.     for (j = 0; j < nvert; j++) {
  245.         for (i = 0; i < nparm; i++) {
  246.             p[j].parm[i] = atof(str_in(fptr, dummy)) ;
  247.         }
  248.     }
  249.  
  250.  
  251.  
  252.                     /* read and print
  253.                     data array */
  254.     fprintf(fp_out, "\n%-79s\n", str_in(fptr, dummy)) ;
  255.     p_x = &data[0] ;
  256.     for (j = 0; j < ndata; j++) {
  257.         for (i = 0; i < ndatval; i++, p_x++)
  258.             *p_x = atof(str_in(fptr, dummy)) ;
  259.     }
  260.     maxiter = 0 ;
  261.     fdatprint(fp_out) ;
  262.  
  263.                     /* calculate function values
  264.                     and print simplex */
  265.     fprintf(fp_out, "\n\ncalculating function values: ") ;
  266.     for (j = 0; j < nvert; j++) {
  267.         func(&p[j]) ;
  268.         fprintf(fp_out, "%d ", j) ;
  269.     }
  270.     fsprint(fp_out, "\n\nsimplex:\n") ;
  271.  
  272.     fclose(fptr) ;
  273.     return (OK) ;
  274. }                /* END OF READ_DATA            */
  275.